package com.wh.maker.generator.main;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.util.StrUtil;
import com.wh.maker.generator.JarGenerator;
import com.wh.maker.generator.ScriptGenerator;
import com.wh.maker.generator.file.DynamicFileGenerator;
import com.wh.maker.meta.Meta;
import com.wh.maker.meta.MetaManager;
import freemarker.template.TemplateException;

import java.io.File;
import java.io.IOException;

public abstract class GenerateTemplate {

    Meta meta;
    //项目根目录  绝对路径
    String projectPath;
    //输出根目录  绝对路径
    String outputPath;//输出根目录
    //resoures目录 绝对路径
    String resourcePath;  //resource目录绝对路径


    String inputFilePath;   //要复制的文件 绝对路径
    String outputFilePath;  //要粘贴的文件 绝对路径

    //带Java包的绝对路径
    String outputJavaPackagePath;

    // 带参数的构造函数
    public GenerateTemplate(Meta meta) {
        this.meta = meta != null ? meta : MetaManager.getMeta();
        initializePaths();
    }

    // 无参构造函数，使用默认值
    public GenerateTemplate() {
        this.meta = MetaManager.getMeta();
        initializePaths();
    }

    // 初始化路径相关属性
    private void initializePaths() {
        this.projectPath = System.getProperty("user.dir");
        this.outputPath = projectPath + File.separator + "output" + File.separator + meta.getName();
        ClassPathResource classPathResource = new ClassPathResource("");
        this.resourcePath = classPathResource.getAbsolutePath();

        String outputBasePackage = meta.getBasePackage();
        String outputBasePackagePath = StrUtil.join("/", StrUtil.split(outputBasePackage, '.'));
        this.outputJavaPackagePath = outputPath + File.separator + "src/main/java/" + File.separator +outputBasePackagePath;
    }



    //执行生成操作
    public final  void doGenerate () throws TemplateException, IOException, InterruptedException {

        System.out.println("映射的Meta值"+ meta);
        //输出目录没有先生成
        if (!FileUtil.exist(outputPath)) {
            FileUtil.mkdir(outputPath);
        }
        //复制原始文件
        String sourceCopyDestPath = copySource();

        //生成代码
        generateCode();

        //构建jar包
        String jarPath = buildJar();

        //生成bar文件
        String shellOutputFilePath = BuildScript(jarPath);

        //生成精简程序
        buildDist(jarPath, shellOutputFilePath,sourceCopyDestPath);
    }


    //生成精简程序
    private void buildDist(String jarPath, String shellOutputFilePath,String sourceCopyDestPath) {
        // 生成精简版的程序（产物包）
        String distOutputPath = outputPath + "-dist";
        // - 拷贝 jar 包
        String targetAbsolutePath = distOutputPath + File.separator + "target";
        FileUtil.mkdir(targetAbsolutePath);
        String jarAbsolutePath = outputPath + File.separator + jarPath;
        FileUtil.copy(jarAbsolutePath, targetAbsolutePath, true);
        // - 拷贝脚本文件
        FileUtil.copy(shellOutputFilePath + ".bat", distOutputPath, true);
        // - 拷贝源模板文件
        FileUtil.copy(sourceCopyDestPath, distOutputPath, true);
    }

    //生成shell文件
    private String BuildScript(String jarPath) throws IOException {
        // 封装脚本
        String shellOutputFilePath = outputPath + File.separator + "generator";
        ScriptGenerator.doGenerate(shellOutputFilePath, jarPath);
        return shellOutputFilePath;
    }

    //构建jar包
    private String buildJar() throws IOException, InterruptedException {
        // 构建 jar 包
        JarGenerator.doGenerate(outputPath);
        String jarName = String.format("%s-%s-jar-with-dependencies.jar", meta.getName(), meta.getVersion());
        String jarPath = "target/" + jarName;
        return jarPath;
    }

    //生成模板文件
    private void generateCode() throws IOException, TemplateException {

        //生成模型文件
        inputFilePath = resourcePath + "templates/java/model/DataModel.java.ftl";
        outputFilePath = outputJavaPackagePath + File.separator + "model" + File.separator + "DataModel.java";
        DynamicFileGenerator.doGenerate(inputFilePath, outputFilePath, meta);

        // cli.command.ConfigCommand
        inputFilePath = resourcePath + File.separator + "templates/java/cli/command/ConfigCommand.java.ftl";
        outputFilePath = outputJavaPackagePath + "/cli/command/ConfigCommand.java";
        DynamicFileGenerator.doGenerate(inputFilePath, outputFilePath, meta);

        // cli.command.GenerateCommand
        inputFilePath = resourcePath + File.separator + "templates/java/cli/command/GenerateCommand.java.ftl";
        outputFilePath = outputJavaPackagePath + "/cli/command/GenerateCommand.java";
        DynamicFileGenerator.doGenerate(inputFilePath, outputFilePath, meta);

        // cli.command.ListCommand
        inputFilePath = resourcePath + File.separator + "templates/java/cli/command/ListCommand.java.ftl";
        outputFilePath = outputJavaPackagePath + "/cli/command/ListCommand.java";
        DynamicFileGenerator.doGenerate(inputFilePath, outputFilePath, meta);

        // cli.CommandExecutor
        inputFilePath = resourcePath + File.separator + "templates/java/cli/CommandExecutor.java.ftl";
        outputFilePath = outputJavaPackagePath + "/cli/CommandExecutor.java";
        DynamicFileGenerator.doGenerate(inputFilePath, outputFilePath, meta);

        // Main
        inputFilePath = resourcePath + File.separator + "templates/java/Main.java.ftl";
        outputFilePath = outputJavaPackagePath + "/Main.java";
        DynamicFileGenerator.doGenerate(inputFilePath, outputFilePath, meta);

        // generator.DynamicGenerator
        inputFilePath = resourcePath + File.separator + "templates/java/generator/DynamicFileGenerator.java.ftl";
        outputFilePath = outputJavaPackagePath + "/generator/DynamicFileGenerator.java";
        DynamicFileGenerator.doGenerate(inputFilePath, outputFilePath, meta);
        // generator.MainGenerator
        inputFilePath = resourcePath + File.separator + "templates/java/generator/FileGenerator.java.ftl";
        outputFilePath = outputJavaPackagePath + "/generator/FileGenerator.java";
        DynamicFileGenerator.doGenerate(inputFilePath, outputFilePath, meta);
        // generator.StaticGenerator
        inputFilePath = resourcePath + File.separator + "templates/java/generator/StaticFileGenerator.java.ftl";
        outputFilePath = outputJavaPackagePath + "/generator/StaticFileGenerator.java";
        DynamicFileGenerator.doGenerate(inputFilePath, outputFilePath, meta);


        //pom.xml
        inputFilePath = resourcePath + File.separator + "templates/pom.xml.ftl";
        outputFilePath = outputPath + File.separator + "pom.xml";
        DynamicFileGenerator.doGenerate(inputFilePath, outputFilePath, meta);


        //README.md
        inputFilePath = resourcePath + File.separator + "templates/README.md.ftl";
        outputFilePath = outputPath + File.separator + "README.md";
        DynamicFileGenerator.doGenerate(inputFilePath, outputFilePath, meta);
    }

    //生成源文件
    private String copySource() {
        String sourceRootPath = meta.getFileConfig().getSourceRootPath();
        String sourceCopyDestPath = outputPath + File.separator + ".source";
        FileUtil.copy(sourceRootPath, sourceCopyDestPath, false);
        return sourceCopyDestPath;
    }
}
